﻿///////////////////////////////////////////////////////
//
// XDesigner.ORM 
//
// autohr : yuans
//
// date: 2011-2-23
//
// email  : yyf9989@hotmail.com
// 
//
///////////////////////////////////////////////////////

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

namespace XDesigner.ORM.DOM
{
    /// <summary>
    /// ORM relation information
    /// </summary>
    [Serializable()]
    [System.ComponentModel.TypeConverter( typeof( ORMRelationInfoTypeConver))]
    public class ORMRelationInfo : ICloneable
    {
        /// <summary>
        /// Initialize instance
        /// </summary>
        public ORMRelationInfo()
        {
        }

        private ORMPropertyInfo _OwnerProperty = null;
        [Browsable( false )]
        [System.Xml.Serialization.XmlIgnore()]
        public ORMPropertyInfo OwnerProperty
        {
            get { return _OwnerProperty; }
            set { _OwnerProperty = value; }
        }

        private ORMRelationStyle _Style = ORMRelationStyle.Auto;
        /// <summary>
        /// Relation style
        /// </summary>
        public ORMRelationStyle Style
        {
            get { return _Style; }
            set { _Style = value; }
        }


        private bool _LogReference = true;
        [System.ComponentModel.DefaultValue( true )]
        public bool LogReference
        {
            get { return _LogReference; }
            set { _LogReference = value; }
        }


        private ORMRelationStyle _RuntimeStyle = ORMRelationStyle.None;
        /// <summary>
        /// Relation style at runtime
        /// </summary>
        [System.Xml.Serialization.XmlIgnore()]
        [Browsable( false )]
        public ORMRelationStyle RuntimeStyle
        {
            get 
            {
                return _RuntimeStyle; 
            }
            set
            {
                _RuntimeStyle = value; 
            }
        }


        private string _ParentPropertyName = null;
        /// <summary>
        /// Parent field name
        /// </summary>
        public string ParentPropertyName
        {
            get
            {
                return _ParentPropertyName;
            }
            set
            {
                _ParentPropertyName = value;
            }
        }


        private string _RuntimeParentPropertyName = null;
        /// <summary>
        /// Parent field name
        /// </summary>
        public string RuntimeParentPropertyName
        {
            get
            {
                if (_RuntimeParentPropertyName == null)
                    return _ParentPropertyName;
                else
                    return _RuntimeParentPropertyName; 
            }
            set
            {
                _RuntimeParentPropertyName = value;
            }
        }

        internal ORMPropertyInfo ParentProperty
        {
            get
            {
                if (this.OwnerProperty == null)
                    return null;
                if (Util.HasContent(this.RuntimeParentPropertyName))
                {
                    ORMPropertyInfo p = this.OwnerProperty.OwnerType.Properties.GetByName(
                        this.RuntimeParentPropertyName);
                    if (p == null)
                    {
                        if( this.RuntimeStyle == ORMRelationStyle.OneToOne )
                        {
                            p = this.OwnerProperty ;
                        }
                        else
                        {
                            p = this.OwnerProperty.OwnerType.KeyProperty;
                        }
                    }
                    return p;
                }
                else
                {
                    if (this.RuntimeStyle == ORMRelationStyle.OneToOne)
                    {
                        return this.OwnerProperty;
                    }
                    else
                    {
                        return this.OwnerProperty.OwnerType.KeyProperty;
                    }
                }
            }
        }
        
        private string _ChildPropertyName = null;
        /// <summary>
        /// Child field name
        /// </summary>
        public string ChildPropertyName
        {
            get { return _ChildPropertyName; }
            set { _ChildPropertyName = value; }
        }

        private ORMPropertyInfo _ChildProperty = null;

        internal ORMPropertyInfo ChildProperty
        {
            get { return _ChildProperty; }
            set { _ChildProperty = value; }
        }
        //{
        //    get
        //    {
        //        if (this.OwnerProperty != null)
        //        {
        //            ORMTypeInfo type = this.OwnerProperty.PropertyType .OwnerType;
        //            ORMPropertyInfo p = type.Properties.GetByName(this.ChildPropertyName);
        //            if (p == null)
        //            {
        //                p = type.KeyProperty;
        //            }
        //            return p;
        //        }
        //        else
        //        {
        //            return null;
        //        }
        //    }
        //}

        //private string _CustomCommandText = null;
        ///// <summary>
        ///// Custom command text for query data
        ///// </summary>
        //public string CustomCommandText
        //{
        //    get
        //    {
        //        return _CustomCommandText;
        //    }
        //    set
        //    {
        //        _CustomCommandText = value;
        //    }
        //}


        private bool _UniteDeleteForDelete = false;
        /// <summary>
        /// When delete parent record , delete all child records
        /// </summary>
        [System.ComponentModel.DefaultValue(false)]
        public bool UniteDeleteForDelete
        {
            get
            {
                return _UniteDeleteForDelete; 
            }
            set
            {
                _UniteDeleteForDelete = value; 
            }
        }

        private bool _UniteDeleteForUpdate = false;
        /// <summary>
        /// When update parent record , delete all child records and insert new child reocords
        /// </summary>
        [System.ComponentModel.DefaultValue(false)]
        public bool UniteDeleteForUpdate
        {
            get
            {
                return _UniteDeleteForUpdate; 
            }
            set
            {
                _UniteDeleteForUpdate = value; 
            }
        }
         
        object ICloneable.Clone()
        {
            ORMRelationInfo rel = new ORMRelationInfo();
            rel._ChildPropertyName = this._ChildPropertyName;
            rel._ParentPropertyName = this._ParentPropertyName;
            rel._Style = this._Style;
            rel._UniteDeleteForDelete = this._UniteDeleteForDelete;
            rel._UniteDeleteForUpdate = this._UniteDeleteForUpdate;
            rel._LogReference = this._LogReference;
            //rel.ParentProperty = this.ParentProperty;
            //rel.ChildProperty = this.ChildProperty;

            return rel;
        }

        public ORMRelationInfo Clone()
        {
            return (ORMRelationInfo)((ICloneable)this).Clone();
        }

    }


    public class ORMRelationInfoTypeConver : System.ComponentModel.TypeConverter
    {
        public override bool GetPropertiesSupported(ITypeDescriptorContext context)
        {
            return true;
        }
        public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
        {
            return TypeDescriptor.GetProperties(typeof(ORMRelationInfo), attributes);
        }
    }


    [Serializable()]
    public class ORMRelationList : System.Collections.CollectionBase
    {
        public ORMRelationList()
        {
        }

        public ORMRelationInfo this[int index]
        {
            get
            {
                return (ORMRelationInfo)this.List[index];
            }
        }

        public int Add(ORMRelationInfo item)
        {
            return this.List.Add(item);
        }

        public void Remove(ORMRelationInfo item)
        {
            this.List.Remove(item);
        }
    }
}
